﻿// <copyright file="SaveModelButton.cs" company="City of Portland, BES-ASM">
// </copyright>
// <summary>SaveModelButton class</summary>

namespace BESASM.EMGAATS.UI.ArcMap
{
  using System;
  using System.Collections.Generic;
  using System.IO;
  using System.Linq;
  using System.Text;
  using BESASM.EMGAATS.Arc;
  using BESASM.EMGAATS.BusinessClasses;
  using BESASM.EMGAATS.DataAccess;
  using ESRI.ArcGIS.Carto;
  using ESRI.ArcGIS.Catalog;
  using ESRI.ArcGIS.CatalogUI;
  using ESRI.ArcGIS.DataSourcesGDB;
  using ESRI.ArcGIS.esriSystem;
  using ESRI.ArcGIS.Geodatabase;
  using ESRI.ArcGIS.Geometry;

  /// <summary>
  /// A button for saving the selected network entities to a new model database.
  /// </summary>
  public class SaveModelButton : ESRI.ArcGIS.Desktop.AddIns.Button
  {
    /// <summary>
    /// Called by ArcMap when the user clicks the button.
    /// </summary>
    protected override void OnClick()
    {
      FormsUtility.SafeExecute(delegate
      {
        ArcMap.Application.CurrentTool = null;
        this.InternalOnClick();
      });
    }

    /// <summary>
    /// Called by ArcMap when the button is to be updated.
    /// </summary>
    protected override void OnUpdate()
    {
      if (EmgaatsExtension.Instance != null && EmgaatsExtension.Instance.NetworkManager != null && EmgaatsExtension.Instance.NetworkManager.IsLoaded)
      {
        this.Enabled = true;
        ////this.Enabled = EmgaatsExtension.Instance.NumberSelectedEntities(EntityType.Link) > 0;
      }
      else
      {
        this.Enabled = false;
      }
    }

    private void InternalOnClick()
    {
      IGxDialog gxDialog = new GxDialogClass();
      gxDialog.Title = "Save EMGAATS Model Database";
      gxDialog.ObjectFilter = new FileGeodatabaseFilterWrapper();

      if (gxDialog.DoModalSave(ArcMap.Application.hWnd))
      {
        var subnetwork = this.ExtractSelectedNetwork();

        string message = string.Format("Subnetwork extracted:");
        message += Environment.NewLine;
        message += Environment.NewLine + string.Format("({0} links, {1} nodes, {2} areas, {3} directors, {4} weirs, {5} cross-sections)", subnetwork.Links.Count, subnetwork.Nodes.Count, subnetwork.Areas.Count, subnetwork.Directors.Count, subnetwork.Weirs.Count, subnetwork.CrossSections.Count);
        FormsUtility.ShowMessage(message);

        IWorkspaceFactory factory = new FileGDBWorkspaceFactoryClass();
        if (gxDialog.ReplacingObject)
        {
          IWorkspace existing = factory.OpenFromFile(System.IO.Path.Combine(gxDialog.FinalLocation.FullName, gxDialog.Name), ArcMap.Application.hWnd);
          ((IDataset)existing).Delete();
        }

        IWorkspaceName workspaceName = factory.Create(gxDialog.FinalLocation.FullName, gxDialog.Name, null, ArcMap.Application.hWnd);
        IWorkspace workspace = ((IName)workspaceName).Open() as IWorkspace;

        ModelDataAccess dataAccess = new ModelDataAccess();
        dataAccess.Workspace = workspace;
        dataAccess.CreateNetworkSchema();
        dataAccess.SaveNetwork(subnetwork);

        EmgaatsExtension.OpenDatabase(workspace);
      }
      else
      {
        return;
      }
    }

    private BusinessClasses.INetwork ExtractSelectedNetwork()
    {
      IFeatureLayer linkLayer = FeatureLayerUtility.GetEntityLayer(ArcMap.Document.FocusMap, EntityType.Link);

      if (linkLayer == null)
      {
        throw new Exception("Cannot find the link feature layer.");
      }

      List<int> linkIds = new List<int>();

      IFeatureSelection selection = linkLayer as IFeatureSelection;
      IEnumIDs ids = selection.SelectionSet.IDs;
      int oid = ids.Next();
      while (oid != -1)
      {
        ILink link = EmgaatsExtension.Instance.NetworkManager.GetEntityForObjectId<ILink>(oid);
        if (link != null)
        {
          linkIds.Add(link.Id);
        }

        oid = ids.Next();
      }

      return EmgaatsExtension.Instance.NetworkManager.Network.ExtractSubnetwork(linkIds);
    }
  }
}
